package org.zhadoop.streaming.util.datatype;

import java.util.Map;
import java.util.TimeZone;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zhadoop.streaming.config.StreamingConfig;
import org.zhadoop.streaming.exception.ErrorCode;
import org.zhadoop.streaming.exception.StreamingException;
import org.zhadoop.streaming.util.ReflectUtil;

/**
 * 时区格式化类
 * TimeZone 中的格式化的方法，
 * 会把错误的时区也识别成0时区，所以没办法判断输入参数是否正常
 * @author zwd
 *
 */
public class TimeZoneUtils {
	private static final Logger LOG = LoggerFactory.getLogger(TimeZoneUtils.class);
	
	/**
	 * 解析时区字符串，如果错误返回空
	 * 支持GMT+08:00 格式 和 Asia/Shanghai这样的时区格式
	 * 如果格式错误，统一返回null
	 * 1.不能直接ZoneInfo类，这个是java内部类，编译的时候会提示，可能会过期
	 * 2.TimeZone	自身静态类，会在传入的字符串的错误情况下返回0时区，这样就无法判断参数错误
	 * 3.该方法使用反射，不建议频繁调用
	 * 
	 * @param zone
	 * @return
	 * @throws StreamingException
	 */
	public static TimeZone parseTimeZone(String zone) throws StreamingException{
		try {
			return ReflectUtil.on(TimeZone.class).invoke("getTimeZone", zone, false).get();
		} catch (ReflectiveOperationException e) {
			LOG.error("Failed to parse timezone {}.",zone);
			throw new StreamingException("Failed to parse timezone" + zone);
		}
	}
	
	/**
	 * 获取时区
	 * @param config
	 * @return 
	 * @throws StreamingException
	 */
	public static TimeZone getTimeZone(StreamingConfig config) throws StreamingException{
		String strZone = config.getStringValue(StreamingConfig.STREAMING_OPERATOR_TIMEZONE);
		TimeZone timeZone = TimeZoneUtils.parseTimeZone(strZone);
		if(timeZone == null){
			LOG.error(ErrorCode.TOP_ERROR_TIME_ZONE.getFullMessage(strZone));
			throw new StreamingException(ErrorCode.TOP_ERROR_TIME_ZONE,strZone);
		}
		return timeZone;
	}
	
	public static TimeZone getTimeZone(Map<String,String> config) throws StreamingException{
		String strZone = config.get(StreamingConfig.STREAMING_OPERATOR_TIMEZONE);
		TimeZone timeZone = TimeZoneUtils.parseTimeZone(strZone);
		if(timeZone == null){
			LOG.error(ErrorCode.TOP_ERROR_TIME_ZONE.getFullMessage(strZone));
			throw new StreamingException(ErrorCode.TOP_ERROR_TIME_ZONE,strZone);
		}
		return timeZone;
	}
}
